#include <iostream>
#include <string>
#include <assert.h>
using namespace std;

void test_string1()
{
	string s1; // 构造空的string类对象s1
	string s2("hello world"); // 用C格式字符串构造string类对象s2
	string s3(s2); // 拷贝构造s3

	cout << s1 << endl;
	cout << s2 << endl;
	cout << s3 << endl;

	string s4(s2, 6, 3);//从第6个位置开始向后面拷贝3个字母
	cout << s4 << endl;

	string s5(s2, 6, 15);// 第三个参数len大于后面字符长度，有多少拷贝多少拷贝到结尾
	cout << s5 << endl;
	string s6(s2, 6);// 第三个参数默认给npos，是整形的最大值，相当于取所有字符串
	cout << s6 << endl;

	string s7(10, 'x');// 用10个x构造s7
	cout << s7 << endl;
}


void test_string2()
{
	string s1("hello world");
	cout << s1.size() << endl;
	cout << s1.length() << endl;
	cout << s1.capacity() << endl;
	cout << s1.empty() << endl;

	cout << s1 << endl;
	s1.clear();
	cout << s1 << endl;;

	string s2;
	cout << s2.capacity() << endl;// 不同编译器的原始值不同，扩容也不同
	s2.reserve(1000);// 实际考虑内存对齐什么的，会多预留一点
	cout << s2.capacity() << endl;

	string s3("hello world");
	cout << s3.size() << endl;
	s3.resize(50, 'x');
	cout << s3 << endl;
}

void test_string3()
{
	string s1("hello world");
	s1[0] = 'x';
	//s1[20];  内部会检查越界
	cout << s1 << endl;

	for (size_t i = 0; i < s1.size(); ++i)// 普通遍历string，每个字符+1
	{
		s1[i]++;
	}
	cout << s1 << endl;

	string::iterator it = s1.begin();// 迭代器遍历string，每个字符+1
	while (it != s1.end())
	{
		(*it)++;
		it++;
	}
	cout << s1 << endl;

	for (auto& e : s1)// 范围for遍历string，每个字符-1
	{
		e--;
	}
	cout << s1 << endl;

	string::reverse_iterator rit = s1.rbegin();// 迭代器逆置遍历string，每个字符-1
	while (rit != s1.rend())
	{
		cout << *rit;
		(*rit)--;
		++rit;// 注意这里也是++
	}
	cout << endl;
	
	*(s1.begin()) = 'h';// 把第一个字母改成h -> s1[0] = 'h';
	cout << s1 << endl;
}

void test_string4()
{
	string s("hello");
	s.push_back('-');
	s.push_back('-');
	s.append("world");
	cout << s << endl;

	string str("abcdefg");
	s += '@';
	s += str;
	s += "!!!";
	cout << s << endl;

	s.append(++str.begin(), --str.end());
	cout << s << endl;

	string copy(s.begin() + 3, s.end() - 3);
	cout << copy << endl;

	int ival = 2023;
	double dval = 3.14;
	cout << to_string(ival) << endl;
	cout << to_string(dval) << endl;

	string istr = "9999";
	string dstr = "9999.99";
	cout << stoi(istr) << endl;
	cout << stod(dstr) << endl;
}

void DealUrl(const string& url)
{
	// 取出协议
	size_t pos1 = url.find("://");
	if (pos1 == string::npos)
	{
		cout << "非法url" << endl;
		return;
	}
	string protocol = url.substr(0, pos1);
	cout << protocol << endl;

	// 取出域名
	size_t pos2 = url.find('/', pos1 + 3);// 冒号位置+3开始往后找
	if (pos2 == string::npos)
	{
		cout << "非法url" << endl;
		return;
	}
	string domain = url.substr(pos1 + 3, pos2 - pos1 - 3);
	cout << domain << endl;

	// 取出路径
	string uri = url.substr(pos2 + 1);
	cout << uri << endl << endl;
}

void test_string5()
{
	string filename("test.cpp.tar.zip");// 取后缀
	size_t pos = filename.rfind('.');// 反向找
	if (pos != string::npos)
	{
		//string suff = filename.substr(pos, filename.size() - pos);
		string suff = filename.substr(pos);//不用像上一行算长度，直接让默认值取到最后

		cout << suff << endl;
	}

	string url1 = "https://cplusplus.com/reference/string/string/";// 对一个网址进行操作，可以多放几个试试
	DealUrl(url1);
}

//int main()
//{
//	//test_string5();
//
//
//	return 0;
//}

//int main()
//{
//	string a = "hello world";
//	string b = a;
//	if (a.c_str() == b.c_str())
//	{
//		cout << "true" << endl;
//	}
//	else cout << "false" << endl;
//	string c = b;
//	c = "";
//	if (a.c_str() == b.c_str())
//	{
//		cout << "true" << endl;
//	}
//	else cout << "false" << endl;
//	a = "";
//	if (a.c_str() == b.c_str())
//	{
//		cout << "true" << endl;
//	}
//	else cout << "false" << endl;
//	return 0;
//}

//int main()
//{
//	string str("hello world");
//	str.reserve(111);
//	str.resize(5);
//	str.reserve(50);
//	cout << str.size() << " " << str.capacity() << endl;
//	return 0;
//}

//int main()
//{
//	string strText = "How are you?";
//	string strSeparator = " ";
//	string strResult;
//	int size_pos = 0;
//	int size_prev_pos = 0;
//	while ((size_pos = strText.find_first_of(strSeparator, size_pos)) != string::npos)
//	{
//		strResult = strText.substr(size_prev_pos, size_pos - size_prev_pos);
//		cout << strResult << " ";
//		size_prev_pos = ++size_pos;
//	}
//	if (size_prev_pos != strText.size())
//	{
//		strResult = strText.substr(size_prev_pos, size_pos - size_prev_pos);
//		cout << strResult << " ";
//	}
//	cout << endl;
//	return 0;
//}

//415. 字符串相加
//class Solution {
//public:
//	string addStrings(string num1, string num2) {
//		int end1 = num1.size() - 1, end2 = num2.size() - 1;
//		int next = 0;// 表示进位，这里只会是0或1
//		string ret;// 把加后的字符弄到这
//		while (end1 >= 0 || end2 >= 0)// 只要有一个没加完就继续，加完的看做数字0
//		{
//			int val1 = end1 >= 0 ? num1[end1] - '0' : 0;// -'0'转化为数字
//			int val2 = end2 >= 0 ? num2[end2] - '0' : 0;
//			int add = val1 + val2 + next;
//			next = add > 9 ? 1 : 0;// 处理进位
//			写到这想到头插：查文档：
//			ret.insert(0, 1, (add % 10) + '0');// 在ret第0个位置插入1个字符
//			--end1;
//			--end2;
//		}
//		if (next)// 提交后看测试用例有进位没处理到的处理一下
//		{
//			ret.insert(0, 1, '1');
//		}
//		return ret;
//	}
//};
//
//int main()
//{
//	Solution s;
//	cout << s.addStrings("123", "11");
//	return 0;
//}

//class Solution {
//public:
//	int firstUniqChar(string s) {
//		int countArr[26] = { 0 };
//		for (auto e : s)
//		{
//			countArr[e - 'a']++;//相对映射到数组里++
//		}
//		for (int i = 0;i < s.size(); i++)
//		{
//			if (countArr[(s[i] - 'a')] == 1)//从原字符串遍历字符的相对映射
//			{
//				return i;//第一个相对映射为1的就返回其下标
//			}
//		}
//		return -1;//没有出现一次的，输出-1
//	}
//};

//int main()
//{
//	Solution s;
//	cout << s.firstUniqChar("aappwajapakddaopwjaopwjigwahbb");
//	return 0;
//}

class Solution {
public:
	bool isPalindrome(string s) {
		for (auto& e : s)
		{
			e = tolower(e);// 如果是大写就转小写，不是大写就不处理
		}
		int left = 0, right = s.size() - 1;
		while (left < right)
		{
			while (left < right && !isalpha(s[left]))
			{
				left++;
			}
			while (left < right && !isalpha(s[right]))
			{
				right--;
			}
			if (s[left] != s[right])
			{
				return false;
			}
			else
			{
				left++;
				right--;
			}
		}
		return true;
	}
};

int main()
{
	Solution s;
	cout << s.isPalindrome("0P");
	return 0;
}